package widget.drag;

import android.support.v4.view.ScrollingView;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.NestedScrollView;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.webkit.WebView;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.ScrollView;

import library.logger.Logger;


/**
 * Created by apple on 2017/4/17.
 */

public class DragUtils {

    public static boolean isScrollerView(View child) {
        return child instanceof AbsListView
                || child instanceof ScrollView
                || child instanceof WebView
                || child instanceof ScrollingView
                || child instanceof NestedScrollView;
    }


    public static boolean isListViewReachTopEdge(final AbsListView listView) {
        if (listView == null || listView.getAdapter() == null || listView.getAdapter().getCount() == 0)
            return true;
        if (listView.getFirstVisiblePosition() == 0) {
            final View topChildView = listView.getChildAt(0);
            return topChildView.getTop() == 0;
        }
        return false;
    }

    public static boolean isListViewReachBottomEdge(final AbsListView listView) {
        if (listView == null || listView.getAdapter() == null || listView.getAdapter().getCount() == 0)
            return true;
        if (listView.getLastVisiblePosition() == (listView.getCount() - 1)) {
            final View bottomChildView = listView.getChildAt(listView.getLastVisiblePosition() - listView.getFirstVisiblePosition());
            return (listView.getHeight() >= bottomChildView.getBottom());
        }
        return false;
    }


    public static boolean canScroll(View mScrollableView, int direction) {
        if (mScrollableView == null) return false;
        boolean isSlidingUp = direction == -1;
        boolean canScroll = ViewCompat.canScrollVertically(mScrollableView, direction);
        if (canScroll)
            return true;
        int scrollY = 0;
        if (mScrollableView instanceof ScrollView) {
            if (isSlidingUp) {
                scrollY = mScrollableView.getScrollY();
            } else {
                ScrollView sv = ((ScrollView) mScrollableView);
                View child = sv.getChildAt(0);
                scrollY = (child.getBottom() - (sv.getHeight() + sv.getScrollY()));
            }
        } else if (mScrollableView instanceof ListView && ((ListView) mScrollableView).getChildCount() > 0) {
            ListView lv = ((ListView) mScrollableView);
            if (lv.getAdapter() == null) {
            } else if (isSlidingUp) {
                View firstChild = lv.getChildAt(0);
                // Approximate the scroll position based on the top child and the first visible item
                scrollY = lv.getFirstVisiblePosition() * firstChild.getHeight() - firstChild.getTop();
            } else {
                View lastChild = lv.getChildAt(lv.getChildCount() - 1);
                // Approximate the scroll position based on the bottom child and the last visible item
                scrollY = (lv.getAdapter().getCount() - lv.getLastVisiblePosition() - 1) * lastChild.getHeight() + lastChild.getBottom() - lv.getBottom();
            }
        } else if (mScrollableView instanceof RecyclerView && ((RecyclerView) mScrollableView).getChildCount() > 0) {
            RecyclerView rv = ((RecyclerView) mScrollableView);
            RecyclerView.LayoutManager lm = rv.getLayoutManager();
            if (rv.getAdapter() == null) {
            } else if (isSlidingUp) {
                View firstChild = rv.getChildAt(0);
                Logger.simple(lm.findViewByPosition(0).getTop());
                // Approximate the scroll position based on the top child and the first visible item
                scrollY = rv.getChildLayoutPosition(firstChild) * lm.getDecoratedMeasuredHeight(firstChild) - lm.getDecoratedTop(firstChild);
            } else {
                View lastChild = rv.getChildAt(rv.getChildCount() - 1);
                // Approximate the scroll position based on the bottom child and the last visible item
                scrollY = (rv.getAdapter().getItemCount() - 1) * lm.getDecoratedMeasuredHeight(lastChild) + lm.getDecoratedBottom(lastChild) - rv.getBottom();
            }
        } else if (mScrollableView instanceof NestedScrollView) {
            if (isSlidingUp) {
                scrollY = mScrollableView.getScrollY();
            } else {
                NestedScrollView nsv = ((NestedScrollView) mScrollableView);
                View child = nsv.getChildAt(0);
                scrollY = (child.getBottom() - (nsv.getHeight() + nsv.getScrollY()));
            }
        } else if (mScrollableView instanceof WebView) {
            WebView webView = (WebView) mScrollableView;
            scrollY = webView.getScrollY();
        }
        return isSlidingUp ? scrollY > 0 : scrollY < 0;
    }
}
